﻿#pragma once
#include <iostream>
#include <functional>
using namespace std;
namespace smart_pointer
{
	//C++98的智能指针：auto_ptr
	template<class T>
	class auto_ptr
	{
	public:
		// 构造函数
		auto_ptr(T* ptr)
			:_ptr(ptr)
		{
		}
		// 拷贝构造函数
		auto_ptr(auto_ptr<T>& sp)
			:_ptr(sp._ptr)
		{
			// 管理权转移
			sp._ptr = nullptr;
		} 
		//=运算符重载
		auto_ptr<T>& operator=(auto_ptr<T>& ap)
		{
			// 检测是否为⾃⼰给⾃⼰赋值
			if (this != &ap)
			{
				// 释放当前对象中资源
				if (_ptr)
					delete _ptr;
				// 转移ap中资源到当前对象中
				_ptr = ap._ptr;
				ap._ptr = NULL;
			} 
			return* this;
		}
		~auto_ptr()
		{
			if (_ptr)
			{
				cout << "delete:" << _ptr << endl;
				delete _ptr;
			}
		} 
		// 像指针⼀样使⽤
		T & operator*()
		{
			return *_ptr;
		} 
		T* operator->()
		{
			return _ptr;
		}
	private:
		T* _ptr;
	};
	//C++11的智能指针：unique_ptr
	template<class T>
	class unique_ptr
	{
	public:
		//explicit 关键字用于修饰只有一个参数的构造函数，
		// 用来防止编译器进行不期望的隐式类型转换。
		explicit unique_ptr(T* ptr)
			:_ptr(ptr)
		{
		}
		~unique_ptr()
		{
			if (_ptr)
			{
				cout << "delete:" << _ptr << endl;
				delete _ptr;
			}
		}
		// 像指针⼀样使⽤
		T & operator*()
		{
			return *_ptr;
		} 
		T* operator->()
		{
			return _ptr;
		} 
		//delete 关键字用于禁止拷贝构造函数和赋值运算符
		//C++98中只声明不实现，声明为private:
		//C++11中声明为=default
		unique_ptr(const unique_ptr<T>& sp) = delete;
		unique_ptr<T>& operator=(const unique_ptr<T>& sp) = delete;
		unique_ptr(unique_ptr<T>&& sp)
			:_ptr(sp._ptr)
		{
			sp._ptr = nullptr;
		} 
		unique_ptr<T>& operator=(unique_ptr<T>&& sp)
		{
			delete _ptr;
			_ptr = sp._ptr;
			sp._ptr = nullptr;
		}
	private:
		T* _ptr;
	};
	//C++11的智能指针：shared_ptr
	template<class T>
	class shared_ptr
	{
		//定制删除器
	public:
		explicit shared_ptr(T* ptr = nullptr)
			: _ptr(ptr)
			, _pcount(new int(1))
		{
		}
		template<class D>
		shared_ptr(T* ptr, D del)
			: _ptr(ptr)
			, _pcount(new int(1))
			, _del(del)//删除器保存起来
		{
		}
		shared_ptr(const shared_ptr<T>& sp)
			:_ptr(sp._ptr)
			, _pcount(sp._pcount)
			, _del(sp._del)
		{
			++(*_pcount);
		} 
		void release()
		{
			if (--(*_pcount) == 0)
			{
				// 最后⼀个管理的对象，释放资源
				_del(_ptr);
				delete _pcount;
				_ptr = nullptr;
				_pcount = nullptr;
			}
		} 
		shared_ptr<T>& operator=(const shared_ptr<T>& sp)
		{
			if (_ptr != sp._ptr)
			{
				release();
				_ptr = sp._ptr;
				_pcount = sp._pcount;
				++(*_pcount);
				_del = sp._del;
			} 
			return* this;
		}

		~shared_ptr()
		{
			release();
		}

		T* get() const
		{
			return _ptr;
		}
		int use_count() const
		{
			return *_pcount;
		} 
		T& operator*()
		{
			return *_ptr;
		} 
		T* operator->()
		{
			return _ptr;
		}
	private:
		T* _ptr;
		int* _pcount;
		//atomic<int>* _pcount;
		function<void(T*)> _del = [](T* ptr) {delete ptr; };//包装器
	};
	//C++11的智能指针：weak_ptr
	template<class T>
	class weak_ptr
	{
		public:
			weak_ptr()
			{
			}
			weak_ptr(const shared_ptr<T>& sp)
				:_ptr(sp.get())
			{
			}
			weak_ptr<T>& operator=(const shared_ptr<T>& sp)
			{
				_ptr = sp.get();
				return *this;
			}
		private:
			T* _ptr = nullptr;
	};
}
